<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>幻魔K1鼠标控制器DLL 跨语言调用手册</title>
    
    <!-- 核心框架：Bootstrap 5（国内CDN） -->
    <link href="https://lf3-cdn-tos.bytecdntp.com/cdn/expire-100-M/bootstrap/5.3.2/css/bootstrap.min.css" rel="stylesheet">
    
    <!-- 代码高亮：Highlight.js -->
    <link href="https://cdn.bootcdn.net/ajax/libs/highlight.js/11.9.0/styles/vs2015.min.css" rel="stylesheet">
    
    <!-- 图标库：Font Awesome -->
    <link href="https://lf6-cdn-tos.bytecdntp.com/cdn/expire-100-M/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
    
    <!-- 自定义样式（现代简约+专业配色） -->
    <style>
        :root {
            --primary-color: #165DFF;
            --primary-light: #E8F3FF;
            --primary-dark: #0E42CC;
            --text-main: #1D2129;
            --text-secondary: #4E5969;
            --bg-light: #F7F8FA;
            --card-shadow: 0 4px 16px rgba(0, 0, 0, 0.05);
            --card-hover-shadow: 0 8px 24px rgba(22, 93, 255, 0.1);
        }
        
        html {
            scroll-behavior: smooth;
            font-family: 'Inter', 'PingFang SC', 'Microsoft YaHei', sans-serif;
        }
        
        body {
            background-color: var(--bg-light);
            color: var(--text-main);
            line-height: 1.6;
        }
        
        /* 顶部标题栏 */
        .page-header {
            background-color: white;
            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.03);
            padding: 1.2rem 0;
            position: sticky;
            top: 0;
            z-index: 100;
        }
        .page-title {
            font-size: 1.8rem;
            font-weight: 700;
            color: var(--primary-color);
            margin: 0;
            display: flex;
            align-items: center;
            gap: 0.8rem;
        }
        .page-title i {
            font-size: 1.5rem;
        }
        
        /* 导航栏 */
        .nav-container {
            margin-top: 0.8rem;
            overflow-x: auto;
            white-space: nowrap;
            padding-bottom: 0.5rem;
        }
        .nav-link {
            color: var(--text-secondary);
            font-weight: 500;
            padding: 0.5rem 1rem;
            border-radius: 0.4rem;
            transition: all 0.2s ease;
            margin-right: 0.5rem;
        }
        .nav-link:hover {
            color: var(--primary-color);
            background-color: var(--primary-light);
        }
        .nav-link.active {
            color: white;
            background-color: var(--primary-color);
            box-shadow: 0 2px 8px rgba(22, 93, 255, 0.2);
        }
        
        /* 标题样式 */
        .section-title {
            font-size: 1.5rem;
            font-weight: 700;
            color: var(--primary-color);
            margin: 2.5rem 0 1.2rem;
            padding-bottom: 0.5rem;
            border-bottom: 2px solid var(--primary-light);
            display: flex;
            align-items: center;
            gap: 0.6rem;
        }
        .subsection-title {
            font-size: 1.2rem;
            font-weight: 600;
            color: var(--text-main);
            margin: 1.8rem 0 0.8rem;
            display: flex;
            align-items: center;
            gap: 0.5rem;
        }
        .subsection-title::before {
            content: "";
            width: 0.5rem;
            height: 0.5rem;
            border-radius: 50%;
            background-color: var(--primary-color);
        }
        
        /* 代码块样式 */
        .code-container {
            margin: 1.2rem 0;
            border-radius: 0.6rem;
            overflow: hidden;
            box-shadow: var(--card-shadow);
            transition: box-shadow 0.2s ease;
        }
        .code-container:hover {
            box-shadow: var(--card-hover-shadow);
        }
        .code-header {
            background-color: #2D333B;
            color: white;
            padding: 0.8rem 1rem;
            display: flex;
            justify-content: space-between;
            align-items: center;
            cursor: pointer;
        }
        .code-header .language {
            font-weight: 500;
            display: flex;
            align-items: center;
            gap: 0.6rem;
        }
        .code-header .toggle-btn {
            background-color: var(--primary-color);
            color: white;
            border: none;
            padding: 0.3rem 0.8rem;
            border-radius: 0.3rem;
            font-size: 0.9rem;
            transition: background-color 0.2s;
        }
        .code-header .toggle-btn:hover {
            background-color: var(--primary-dark);
        }
        .code-block {
            display: none;
            background-color: #1D2125;
        }
        .code-block.expanded {
            display: block;
        }
        pre {
            margin: 0;
            padding: 1.2rem;
            overflow-x: auto;
        }
        code {
            font-family: 'Fira Code', 'Consolas', monospace;
        }
        
        /* 卡片与组件 */
        .section-card {
            background-color: white;
            border-radius: 0.8rem;
            box-shadow: var(--card-shadow);
            padding: 1.5rem;
            margin-bottom: 1.8rem;
            transition: box-shadow 0.2s ease;
        }
        .section-card:hover {
            box-shadow: var(--card-hover-shadow);
        }
        .term-card {
            background-color: var(--primary-light);
            border: 1px solid #C9E0FF;
            border-radius: 0.5rem;
            padding: 1rem;
            margin-bottom: 1rem;
            color: var(--text-main);
            transition: all 0.2s ease;
        }
        .term-card:hover {
            border-color: var(--primary-color);
            box-shadow: 0 2px 8px rgba(22, 93, 255, 0.1);
        }
        .term-card strong {
            color: var(--primary-color);
        }
        .faq-item {
            border: 1px solid #E5E6EB;
            border-radius: 0.6rem;
            overflow: hidden;
            margin-bottom: 1rem;
            background-color: white;
            transition: box-shadow 0.2s ease;
        }
        .faq-item:hover {
            box-shadow: var(--card-hover-shadow);
        }
        .faq-header {
            background-color: var(--primary-light);
            padding: 1rem 1.2rem;
            cursor: pointer;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }
        .faq-header h3 {
            font-size: 1rem;
            font-weight: 600;
            margin: 0;
            color: var(--primary-color);
        }
        .faq-body {
            padding: 1.2rem;
            border-top: 1px solid #E5E6EB;
        }
        
        /* 提示框 */
        .note, .warning {
            padding: 1rem 1.2rem;
            border-radius: 0.5rem;
            margin: 1.2rem 0;
            display: flex;
            gap: 1rem;
            align-items: flex-start;
        }
        .note {
            background-color: var(--primary-light);
            border-left: 3px solid var(--primary-color);
        }
        .warning {
            background-color: #FFF6E5;
            border-left: 3px solid #FF9F43;
        }
        .note-icon, .warning-icon {
            font-size: 1.3rem;
            margin-top: 0.2rem;
            color: var(--primary-color);
        }
        .warning-icon {
            color: #FF9F43;
        }
        
        /* 列表 */
        .custom-list {
            list-style: none;
            padding-left: 0;
        }
        .custom-list li {
            padding-left: 1.5rem;
            position: relative;
            margin-bottom: 0.8rem;
        }
        .custom-list li::before {
            content: "•";
            color: var(--primary-color);
            position: absolute;
            left: 0.5rem;
            font-weight: 700;
        }
        
        /* 底部 */
        footer {
            background-color: #1D2129;
            color: #C9CDD4;
            padding: 2rem 0;
            margin-top: 3rem;
            text-align: center;
        }
        .footer-logo {
            font-size: 1.2rem;
            font-weight: 600;
            color: white;
            margin-bottom: 0.8rem;
        }
        .footer-copyright {
            font-size: 0.9rem;
        }
    </style>
</head>
<body>
    <!-- 顶部标题+导航 -->
    <header class="page-header">
        <div class="container">
            <h1 class="page-title">
                <i class="fa-solid fa-mouse-pointer"></i>
                幻魔K1鼠标控制器DLL 跨语言调用手册
            </h1>
            <div class="nav-container">
                <a href="#overview" class="nav-link active">概述</a>
                <a href="#general-flow" class="nav-link">通用流程</a>
                <a href="#csharp" class="nav-link">C# 调用</a>
                <a href="#python" class="nav-link">Python 调用</a>
                <a href="#cpp" class="nav-link">C++ 调用</a>
                <a href="#java" class="nav-link">Java 调用</a>
                <a href="#faq" class="nav-link">常见问题</a>
                <a href="#notes" class="nav-link">注意事项</a>
            </div>
        </div>
    </header>

    <!-- 主要内容 -->
    <main class="container py-5">
        <!-- 概述部分 -->
        <section id="overview" class="section-card">
            <h2 class="section-title">一、手册概述</h2>
            
            <h3 class="subsection-title">核心功能</h3>
            <p class="mb-3">
                本DLL提供幻魔K1盒子串口控制鼠标的核心能力，支持串口自动/手动连接、鼠标相对移动、绝对移动等操作，适配Windows 32/64位平台（需与DLL架构一致）。
            </p>

            <h3 class="subsection-title">适用环境</h3>
            <ul class="custom-list mb-4">
                <li>操作系统：Windows 7/8/10/11（32/64位）</li>
                <li>依赖项：安装对应版本的 <strong>Visual C++ Redistributable</strong>（32位装x86，64位装x64）</li>
                <li>权限要求：串口操作需以管理员身份运行程序</li>
                <li>硬件要求：幻魔K1盒子已通过USB连接至电脑（启用串口模式）</li>
            </ul>

            <h3 class="subsection-title">术语说明</h3>
            <div class="row">
                <div class="col-md-6">
                    <div class="term-card">
                        <strong>控制器句柄（HANDLE）</strong>：DLL内部实例标识，所有操作的核心参数，需妥善保存
                    </div>
                </div>
                <div class="col-md-6">
                    <div class="term-card">
                        <strong>波特率</strong>：默认115200（推荐），需与幻魔K1盒子配置一致
                    </div>
                </div>
                <div class="col-md-6">
                    <div class="term-card">
                        <strong>速度参数</strong>：范围0-255，值越大鼠标移动速度越快
                    </div>
                </div>
                <div class="col-md-6">
                    <div class="term-card">
                        <strong>绝对坐标</strong>：基于屏幕分辨率的像素坐标（如1920x1080屏幕中心为(960,540)）
                    </div>
                </div>
                <div class="col-md-6">
                    <div class="term-card">
                        <strong>相对偏移</strong>：相对于当前鼠标位置的偏移量（正数右移/下移，负数左移/上移）
                    </div>
                </div>
            </div>
        </section>

        <!-- 通用调用流程 -->
        <section id="general-flow" class="section-card">
            <h2 class="section-title">二、通用调用流程</h2>
            <p class="mb-4">
                所有语言调用需遵循以下流程，确保资源正确管理（避免串口占用、内存泄漏）：
            </p>
            <div class="bg-white p-4 rounded-lg border border-light mb-4">
                <ol class="custom-list-decimal" style="list-style: decimal inside; padding-left: 0;">
                    <li>加载DLL文件至程序内存</li>
                    <li>创建控制器实例（获取句柄，后续操作依赖此句柄）</li>
                    <li>初始化串口（自动扫描或手动指定COM口）</li>
                    <li>（可选）设置屏幕分辨率（默认自动获取）</li>
                    <li>执行鼠标操作（相对移动、绝对移动）</li>
                    <li class="fw-bold mt-2">操作完成后释放资源：</li>
                    <li class="ms-4">调用 <code class="bg-light px-1 py-0.5 rounded text-danger">CloseSerial</code> 关闭串口</li>
                    <li class="ms-4">调用 <code class="bg-light px-1 py-0.5 rounded text-danger">DestroyController</code> 销毁控制器实例</li>
                    <li class="ms-4">释放DLL占用的内存</li>
                </ol>
            </div>

            <div class="warning">
                <div class="warning-icon"><i class="fa-solid fa-triangle-exclamation"></i></div>
                <div>
                    <strong>重要提示：</strong> 资源释放流程必须执行，否则会导致串口被占用、后续程序无法连接设备。
                </div>
            </div>
        </section>

        <!-- C# 调用指南 -->
        <section id="csharp" class="section-card">
            <h2 class="section-title">三、C# 调用指南</h2>
            
            <h3 class="subsection-title">环境准备</h3>
            <ul class="custom-list mb-4">
                <li>项目平台：设置为与DLL一致的架构（x86/x64，项目属性 → 生成 → 平台目标）</li>
                <li>DLL部署：将 <code>Mouse.dll</code> 复制到程序输出目录（<code>bin\Debug</code>/<code>bin\Release</code>）</li>
                <li>权限配置：右键程序 → 以管理员身份运行，或在项目属性中启用管理员权限</li>
            </ul>

            <h3 class="subsection-title">函数映射（DllImport声明）</h3>
            <div class="code-container">
                <div class="code-header" onclick="toggleCodeBlock(this)">
                    <div class="language">
                        <i class="fa-brands fa-csharp"></i> C# 函数声明
                    </div>
                    <button class="toggle-btn">
                        <i class="fa-solid fa-chevron-down"></i> 展开代码
                    </button>
                </div>
                <div class="code-block">
<pre><code class="language-csharp">using System;
using System.Runtime.InteropServices;
using System.Text;

namespace MagicMouseK1
{
    internal static class MouseDll
    {
        private const string DllPath = "Mouse.dll";

        // 创建控制器实例
        [DllImport(DllPath, CallingConvention = CallingConvention.StdCall)]
        public static extern IntPtr CreateController();

        // 销毁控制器实例
        [DllImport(DllPath, CallingConvention = CallingConvention.StdCall)]
        public static extern bool DestroyController(IntPtr hController);

        // 手动初始化串口
        [DllImport(DllPath, CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
        public static extern bool InitSerial(IntPtr hController, string portName, int baudRate);

        // 自动扫描串口（默认波特率115200）
        [DllImport(DllPath, CallingConvention = CallingConvention.StdCall)]
        public static extern bool InitSerialWithDefaultBaud(IntPtr hController);

        // 关闭串口
        [DllImport(DllPath, CallingConvention = CallingConvention.StdCall)]
        public static extern void CloseSerial(IntPtr hController);

        // 设置屏幕分辨率
        [DllImport(DllPath, CallingConvention = CallingConvention.StdCall)]
        public static extern void SetScreenResolution(IntPtr hController, int width, int height);

        // 相对移动
        [DllImport(DllPath, CallingConvention = CallingConvention.StdCall)]
        public static extern bool SendRelativeMove(IntPtr hController, float dx, float dy, byte speed);

        // 绝对移动
        [DllImport(DllPath, CallingConvention = CallingConvention.StdCall)]
        public static extern bool SendAbsoluteMove(IntPtr hController, int targetX, int targetY, byte speed);

        // 获取连接信息
        [DllImport(DllPath, CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
        public static extern bool GetConnectionInfo(IntPtr hController, StringBuilder buffer, int bufferSize);

        // 检查串口是否初始化成功
        [DllImport(DllPath, CallingConvention = CallingConvention.StdCall)]
        public static extern bool IsInitialized(IntPtr hController);
    }
}</code></pre>
                </div>
            </div>

            <h3 class="subsection-title">完整调用示例</h3>
            <div class="code-container">
                <div class="code-header" onclick="toggleCodeBlock(this)">
                    <div class="language">
                        <i class="fa-brands fa-csharp"></i> C# 示例代码
                    </div>
                    <button class="toggle-btn">
                        <i class="fa-solid fa-chevron-down"></i> 展开代码
                    </button>
                </div>
                <div class="code-block">
<pre><code class="language-csharp">using System;
using System.Text;

namespace MagicMouseK1
{
    class Program
    {
        static void Main(string[] args)
        {
            IntPtr hController = IntPtr.Zero;
            try
            {
                Console.WriteLine("=== 幻魔K1 DLL调用演示（C#）===");

                // 1. 创建控制器实例
                hController = MouseDll.CreateController();
                if (hController == IntPtr.Zero)
                    throw new Exception("创建控制器失败");
                Console.WriteLine("控制器创建成功");

                // 2. 初始化串口（自动扫描）
                bool initOk = MouseDll.InitSerialWithDefaultBaud(hController);
                if (!initOk)
                {
                    // 自动扫描失败，尝试手动连接COM3
                    initOk = MouseDll.InitSerial(hController, "COM3", 115200);
                }
                if (!initOk || !MouseDll.IsInitialized(hController))
                    throw new Exception("串口初始化失败");

                // 获取连接信息
                StringBuilder connInfo = new StringBuilder(256);
                if (MouseDll.GetConnectionInfo(hController, connInfo, 256))
                    Console.WriteLine($"连接成功：{connInfo}");

                // 3. 设置屏幕分辨率
                MouseDll.SetScreenResolution(hController, 1920, 1080);
                Console.WriteLine("已设置屏幕分辨率：1920x1080");

                // 4. 绝对移动到屏幕中心
                int centerX = 1920 / 2;
                int centerY = 1080 / 2;
                bool moveOk = MouseDll.SendAbsoluteMove(hController, centerX, centerY, 150);
                Console.WriteLine(moveOk ? "绝对移动成功" : "绝对移动失败");
                System.Threading.Thread.Sleep(1500);

                // 5. 相对移动（右移50，下移30）
                moveOk = MouseDll.SendRelativeMove(hController, 50, 30, 120);
                Console.WriteLine(moveOk ? "相对移动成功" : "相对移动失败");
                System.Threading.Thread.Sleep(1500);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"错误：{ex.Message}");
            }
            finally
            {
                // 释放资源
                if (hController != IntPtr.Zero)
                {
                    MouseDll.CloseSerial(hController);
                    MouseDll.DestroyController(hController);
                }
                Console.WriteLine("资源已释放");
            }
            Console.WriteLine("按任意键退出...");
            Console.ReadKey();
        }
    }
}</code></pre>
                </div>
            </div>
        </section>

        <!-- Python 调用指南 -->
        <section id="python" class="section-card">
            <h2 class="section-title">四、Python 调用指南</h2>
            
            <h3 class="subsection-title">环境准备</h3>
            <ul class="custom-list mb-4">
                <li>Python版本：3.6+（架构需与DLL一致：32位DLL用32位Python）</li>
                <li>依赖库：安装 <code>pywin32</code>（用于调用Windows API）：<code>pip install pywin32</code></li>
                <li>DLL部署：将 <code>Mouse.dll</code> 放在Python脚本同级目录</li>
            </ul>

            <h3 class="subsection-title">完整调用示例</h3>
            <div class="code-container">
                <div class="code-header" onclick="toggleCodeBlock(this)">
                    <div class="language">
                        <i class="fa-brands fa-python"></i> Python 示例代码
                    </div>
                    <button class="toggle-btn">
                        <i class="fa-solid fa-chevron-down"></i> 展开代码
                    </button>
                </div>
                <div class="code-block">
<pre><code class="language-python">import ctypes
from ctypes import wintypes
import time

# 加载DLL
try:
    mouse_dll = ctypes.WinDLL("Mouse.dll", use_last_error=True)
except OSError as e:
    print(f"DLL加载失败：{e}")
    exit(1)

# 定义函数类型
mouse_dll.CreateController.restype = wintypes.HANDLE
mouse_dll.DestroyController.restype = wintypes.BOOL
mouse_dll.DestroyController.argtypes = (wintypes.HANDLE,)
mouse_dll.InitSerial.restype = wintypes.BOOL
mouse_dll.InitSerial.argtypes = (wintypes.HANDLE, ctypes.c_char_p, ctypes.c_int)
mouse_dll.InitSerialWithDefaultBaud.restype = wintypes.BOOL
mouse_dll.InitSerialWithDefaultBaud.argtypes = (wintypes.HANDLE,)
mouse_dll.CloseSerial.argtypes = (wintypes.HANDLE,)
mouse_dll.SetScreenResolution.argtypes = (wintypes.HANDLE, ctypes.c_int, ctypes.c_int)
mouse_dll.SendRelativeMove.restype = wintypes.BOOL
mouse_dll.SendRelativeMove.argtypes = (wintypes.HANDLE, ctypes.c_float, ctypes.c_float, ctypes.c_ubyte)
mouse_dll.SendAbsoluteMove.restype = wintypes.BOOL
mouse_dll.SendAbsoluteMove.argtypes = (wintypes.HANDLE, ctypes.c_int, ctypes.c_int, ctypes.c_ubyte)
mouse_dll.GetConnectionInfo.restype = wintypes.BOOL
mouse_dll.GetConnectionInfo.argtypes = (wintypes.HANDLE, ctypes.c_char_p, ctypes.c_int)
mouse_dll.IsInitialized.restype = wintypes.BOOL
mouse_dll.IsInitialized.argtypes = (wintypes.HANDLE,)

def main():
    h_controller = None
    try:
        print("=== 幻魔K1 DLL调用演示（Python）===")
        # 1. 创建控制器
        h_controller = mouse_dll.CreateController()
        if not h_controller:
            raise Exception("控制器创建失败")
        print("控制器创建成功")

        # 2. 初始化串口
        init_ok = mouse_dll.InitSerialWithDefaultBaud(h_controller)
        if not init_ok:
            init_ok = mouse_dll.InitSerial(h_controller, b"COM3", 115200)
        if not init_ok or not mouse_dll.IsInitialized(h_controller):
            raise Exception("串口初始化失败")

        # 获取连接信息
        conn_info = ctypes.create_string_buffer(256)
        if mouse_dll.GetConnectionInfo(h_controller, conn_info, 256):
            print(f"连接成功：{conn_info.value.decode('gbk')}")

        # 3. 设置分辨率
        mouse_dll.SetScreenResolution(h_controller, 1920, 1080)
        print("屏幕分辨率：1920x1080")

        # 4. 绝对移动到中心
        center_x = 1920 // 2
        center_y = 1080 // 2
        move_ok = mouse_dll.SendAbsoluteMove(h_controller, center_x, center_y, 150)
        print("绝对移动成功" if move_ok else "绝对移动失败")
        time.sleep(1.5)

        # 5. 相对移动
        move_ok = mouse_dll.SendRelativeMove(h_controller, 50.0, 30.0, 120)
        print("相对移动成功" if move_ok else "相对移动失败")
        time.sleep(1.5)
    except Exception as e:
        print(f"错误：{e}")
    finally:
        # 释放资源
        if h_controller:
            mouse_dll.CloseSerial(h_controller)
            mouse_dll.DestroyController(h_controller)
        print("资源已释放")

if __name__ == "__main__":
    main()
    input("按任意键退出...")</code></pre>
                </div>
            </div>
        </section>

        <!-- C++ 调用指南 -->
        <section id="cpp" class="section-card">
            <h2 class="section-title">五、C++ 调用指南</h2>
            
            <h3 class="subsection-title">环境准备</h3>
            <ul class="custom-list mb-4">
                <li>编译器：Visual Studio 2017+（项目平台需与DLL架构一致）</li>
                <li>字符集：项目属性 → 高级 → 字符集 → 多字节字符集</li>
                <li>DLL部署：将 <code>Mouse.dll</code> 复制到项目输出目录（<code>Debug</code>/<code>Release</code>）</li>
            </ul>

            <h3 class="subsection-title">完整调用示例</h3>
            <div class="code-container">
                <div class="code-header" onclick="toggleCodeBlock(this)">
                    <div class="language">
                        <i class="fa-solid fa-c"></i> C++ 示例代码
                    </div>
                    <button class="toggle-btn">
                        <i class="fa-solid fa-chevron-down"></i> 展开代码
                    </button>
                </div>
                <div class="code-block">
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;string&gt;
#include &lt;windows.h&gt;
using namespace std;

// 函数指针类型定义
typedef HANDLE(__stdcall* CreateControllerFunc)();
typedef BOOL(__stdcall* DestroyControllerFunc)(HANDLE);
typedef BOOL(__stdcall* InitSerialFunc)(HANDLE, const char*, int);
typedef BOOL(__stdcall* InitSerialWithDefaultBaudFunc)(HANDLE);
typedef void(__stdcall* CloseSerialFunc)(HANDLE);
typedef void(__stdcall* SetScreenResolutionFunc)(HANDLE, int, int);
typedef BOOL(__stdcall* SendRelativeMoveFunc)(HANDLE, float, float, BYTE);
typedef BOOL(__stdcall* SendAbsoluteMoveFunc)(HANDLE, int, int, BYTE);
typedef BOOL(__stdcall* GetConnectionInfoFunc)(HANDLE, char*, int);
typedef BOOL(__stdcall* IsInitializedFunc)(HANDLE);

// 资源自动释放类
class ResourceGuard {
public:
    ResourceGuard(HMODULE& dll, HANDLE& ctrl, DestroyControllerFunc destroy, CloseSerialFunc close)
        : hDll(dll), hController(ctrl), destroyFunc(destroy), closeFunc(close) {}
    ~ResourceGuard() {
        if (hController) {
            closeFunc(hController);
            destroyFunc(hController);
        }
        if (hDll) FreeLibrary(hDll);
        cout &lt;&lt; "资源已释放" &lt;&lt; endl;
    }
private:
    HMODULE& hDll;
    HANDLE& hController;
    DestroyControllerFunc destroyFunc;
    CloseSerialFunc closeFunc;
};

int main() {
    HMODULE hDll = nullptr;
    HANDLE hController = nullptr;
    try {
        cout &lt;&lt; "=== 幻魔K1 DLL调用演示（C++）===" &lt;&lt; endl;
        // 加载DLL
        hDll = LoadLibraryA("Mouse.dll");
        if (!hDll) throw runtime_error("DLL加载失败");

        // 获取函数指针
        CreateControllerFunc CreateController = (CreateControllerFunc)GetProcAddress(hDll, "CreateController");
        DestroyControllerFunc DestroyController = (DestroyControllerFunc)GetProcAddress(hDll, "DestroyController");
        InitSerialFunc InitSerial = (InitSerialFunc)GetProcAddress(hDll, "InitSerial");
        InitSerialWithDefaultBaudFunc InitSerialWithDefaultBaud = (InitSerialWithDefaultBaudFunc)GetProcAddress(hDll, "InitSerialWithDefaultBaud");
        CloseSerialFunc CloseSerial = (CloseSerialFunc)GetProcAddress(hDll, "CloseSerial");
        SetScreenResolutionFunc SetScreenResolution = (SetScreenResolutionFunc)GetProcAddress(hDll, "SetScreenResolution");
        SendRelativeMoveFunc SendRelativeMove = (SendRelativeMoveFunc)GetProcAddress(hDll, "SendRelativeMove");
        SendAbsoluteMoveFunc SendAbsoluteMove = (SendAbsoluteMoveFunc)GetProcAddress(hDll, "SendAbsoluteMove");
        GetConnectionInfoFunc GetConnectionInfo = (GetConnectionInfoFunc)GetProcAddress(hDll, "GetConnectionInfo");
        IsInitializedFunc IsInitialized = (IsInitializedFunc)GetProcAddress(hDll, "IsInitialized");

        if (!CreateController || !DestroyController) throw runtime_error("函数绑定失败");

        // 资源自动释放
        ResourceGuard guard(hDll, hController, DestroyController, CloseSerial);

        // 1. 创建控制器
        hController = CreateController();
        if (!hController) throw runtime_error("控制器创建失败");
        cout &lt;&lt; "控制器创建成功" &lt;&lt; endl;

        // 2. 初始化串口
        bool initOk = InitSerialWithDefaultBaud(hController);
        if (!initOk) initOk = InitSerial(hController, "COM3", 115200);
        if (!initOk || !IsInitialized(hController)) throw runtime_error("串口初始化失败");

        // 连接信息
        char connInfo[256] = {0};
        if (GetConnectionInfo(hController, connInfo, 256))
            cout &lt;&lt; "连接成功：" &lt;&lt; connInfo &lt;&lt; endl;

        // 3. 设置分辨率
        SetScreenResolution(hController, 1920, 1080);
        cout &lt;&lt; "屏幕分辨率：1920x1080" &lt;&lt; endl;

        // 4. 绝对移动
        int centerX = 1920 / 2, centerY = 1080 / 2;
        BOOL moveOk = SendAbsoluteMove(hController, centerX, centerY, 150);
        cout &lt;&lt; (moveOk ? "绝对移动成功" : "绝对移动失败") &lt;&lt; endl;
        Sleep(1500);

        // 5. 相对移动
        moveOk = SendRelativeMove(hController, 50.0f, 30.0f, 120);
        cout &lt;&lt; (moveOk ? "相对移动成功" : "相对移动失败") &lt;&lt; endl;
        Sleep(1500);
    }
    catch (const exception& e) {
        cout &lt;&lt; "错误：" &lt;&lt; e.what() &lt;&lt; endl;
    }
    system("pause");
    return 0;
}</code></pre>
                </div>
            </div>
        </section>

        <!-- 新增Java调用指南 -->
        <section id="java" class="section-card">
            <h2 class="section-title">六、Java 调用指南（基于JNA）</h2>
            
            <h3 class="subsection-title">环境准备</h3>
            <ul class="custom-list mb-4">
                <li>Java版本：JDK 8+（32/64位需与DLL一致）</li>
                <li>依赖库：引入 <code>jna</code>（Maven依赖如下）：
<pre><code class="language-xml">&lt;dependency&gt;
    &lt;groupId&gt;net.java.dev.jna&lt;/groupId&gt;
    &lt;artifactId&gt;jna&lt;/artifactId&gt;
    &lt;version&gt;5.13.0&lt;/version&gt;
&lt;/dependency&gt;</code></pre>
                </li>
                <li>DLL部署：将 <code>Mouse.dll</code> 放在Java项目的 <code>resources</code> 目录，或添加到系统PATH</li>
            </ul>

            <h3 class="subsection-title">JNA接口定义</h3>
            <div class="code-container">
                <div class="code-header" onclick="toggleCodeBlock(this)">
                    <div class="language">
                        <i class="fa-brands fa-java"></i> JNA接口
                    </div>
                    <button class="toggle-btn">
                        <i class="fa-solid fa-chevron-down"></i> 展开代码
                    </button>
                </div>
                <div class="code-block">
<pre><code class="language-java">import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.ByteByReference;
import com.sun.jna.ptr.IntByReference;

// JNA接口映射DLL函数
public interface MouseDll extends Library {
    MouseDll INSTANCE = Native.load("Mouse", MouseDll.class);

    // 创建控制器实例（返回句柄）
    Pointer CreateController();

    // 销毁控制器实例
    boolean DestroyController(Pointer hController);

    // 手动初始化串口
    boolean InitSerial(Pointer hController, String portName, int baudRate);

    // 自动扫描串口（默认波特率115200）
    boolean InitSerialWithDefaultBaud(Pointer hController);

    // 关闭串口
    void CloseSerial(Pointer hController);

    // 设置屏幕分辨率
    void SetScreenResolution(Pointer hController, int width, int height);

    // 相对移动
    boolean SendRelativeMove(Pointer hController, float dx, float dy, byte speed);

    // 绝对移动
    boolean SendAbsoluteMove(Pointer hController, int targetX, int targetY, byte speed);

    // 获取连接信息
    boolean GetConnectionInfo(Pointer hController, byte[] buffer, int bufferSize);

    // 检查串口是否初始化成功
    boolean IsInitialized(Pointer hController);
}</code></pre>
                </div>
            </div>

            <h3 class="subsection-title">完整调用示例</h3>
            <div class="code-container">
                <div class="code-header" onclick="toggleCodeBlock(this)">
                    <div class="language">
                        <i class="fa-brands fa-java"></i> Java 示例代码
                    </div>
                    <button class="toggle-btn">
                        <i class="fa-solid fa-chevron-down"></i> 展开代码
                    </button>
                </div>
                <div class="code-block">
<pre><code class="language-java">import com.sun.jna.Pointer;

public class MagicMouseDemo {
    public static void main(String[] args) {
        MouseDll dll = MouseDll.INSTANCE;
        Pointer hController = null;
        try {
            System.out.println("=== 幻魔K1 DLL调用演示（Java）===");

            // 1. 创建控制器
            hController = dll.CreateController();
            if (hController == null) throw new Exception("控制器创建失败");
            System.out.println("控制器创建成功");

            // 2. 初始化串口
            boolean initOk = dll.InitSerialWithDefaultBaud(hController);
            if (!initOk) {
                initOk = dll.InitSerial(hController, "COM3", 115200);
            }
            if (!initOk || !dll.IsInitialized(hController)) {
                throw new Exception("串口初始化失败");
            }

            // 获取连接信息
            byte[] connInfo = new byte[256];
            if (dll.GetConnectionInfo(hController, connInfo, connInfo.length)) {
                String info = new String(connInfo, "GBK").trim();
                System.out.println("连接成功：" + info);
            }

            // 3. 设置屏幕分辨率
            dll.SetScreenResolution(hController, 1920, 1080);
            System.out.println("屏幕分辨率：1920x1080");

            // 4. 绝对移动到中心
            int centerX = 1920 / 2;
            int centerY = 1080 / 2;
            boolean moveOk = dll.SendAbsoluteMove(hController, centerX, centerY, (byte) 150);
            System.out.println(moveOk ? "绝对移动成功" : "绝对移动失败");
            Thread.sleep(1500);

            // 5. 相对移动
            moveOk = dll.SendRelativeMove(hController, 50.0f, 30.0f, (byte) 120);
            System.out.println(moveOk ? "相对移动成功" : "相对移动失败");
            Thread.sleep(1500);
        } catch (Exception e) {
            System.err.println("错误：" + e.getMessage());
        } finally {
            // 释放资源
            if (hController != null) {
                dll.CloseSerial(hController);
                dll.DestroyController(hController);
            }
            System.out.println("资源已释放");
        }
    }
}</code></pre>
                </div>
            </div>
        </section>

        <!-- 常见问题 -->
        <section id="faq" class="section-card">
            <h2 class="section-title">七、常见问题</h2>
            
            <div class="faq-item">
                <div class="faq-header" onclick="toggleFaq(this)">
                    <h3>DLL加载失败（错误码2/126）</h3>
                    <i class="fa-solid fa-chevron-down"></i>
                </div>
                <div class="faq-body" style="display: none;">
                    <strong>可能原因：</strong>
                    <ul class="custom-list mt-1">
                        <li>DLL文件未放在程序运行目录</li>
                        <li>DLL架构与程序不匹配（如32位程序用64位DLL）</li>
                        <li>缺少Visual C++运行库</li>
                    </ul>
                    <strong>解决方法：</strong>
                    <ul class="custom-list mt-2">
                        <li>将DLL与程序放在同一目录</li>
                        <li>确认项目平台与DLL架构一致</li>
                        <li>安装对应版本的Visual C++ Redistributable</li>
                    </ul>
                </div>
            </div>

            <div class="faq-item">
                <div class="faq-header" onclick="toggleFaq(this)">
                    <h3>串口初始化失败（错误码5/123）</h3>
                    <i class="fa-solid fa-chevron-down"></i>
                </div>
                <div class="faq-body" style="display: none;">
                    <strong>可能原因：</strong>
                    <ul class="custom-list mt-1">
                        <li>未以管理员身份运行程序</li>
                        <li>波特率与幻魔K1盒子不一致</li>
                        <li>串口被其他程序占用（如串口助手）</li>
                        <li>USB连接松动或驱动未安装</li>
                    </ul>
                    <strong>解决方法：</strong>
                    <ul class="custom-list mt-2">
                        <li>右键程序 → 以管理员身份运行</li>
                        <li>确认波特率为115200（默认）</li>
                        <li>关闭其他串口工具</li>
                        <li>重新插拔USB并安装驱动</li>
                    </ul>
                </div>
            </div>

            <div class="faq-item">
                <div class="faq-header" onclick="toggleFaq(this)">
                    <h3>移动操作返回false</h3>
                    <i class="fa-solid fa-chevron-down"></i>
                </div>
                <div class="faq-body" style="display: none;">
                    <strong>可能原因：</strong>
                    <ul class="custom-list mt-1">
                        <li>串口未初始化成功</li>
                        <li>控制器句柄无效（未创建或已销毁）</li>
                        <li>速度参数超出0-255范围</li>
                        <li>绝对坐标超出屏幕分辨率范围</li>
                    </ul>
                    <strong>解决方法：</strong>
                    <ul class="custom-list mt-2">
                        <li>调用<code>IsInitialized</code>确认串口已连接</li>
                        <li>检查控制器句柄是否有效</li>
                        <li>确保速度参数在0-255之间</li>
                        <li>核对屏幕分辨率与坐标值</li>
                    </ul>
                </div>
            </div>
        </section>

        <!-- 注意事项 -->
        <section id="notes" class="section-card">
            <h2 class="section-title">八、注意事项</h2>
            <div class="row">
                <div class="col-md-6 col-lg-4">
                    <div class="term-card">
                        <strong>句柄管理：</strong> 控制器句柄不可随意修改或提前释放
                    </div>
                </div>
                <div class="col-md-6 col-lg-4">
                    <div class="term-card">
                        <strong>资源释放：</strong> 必须先关串口，再销毁控制器
                    </div>
                </div>
                <div class="col-md-6 col-lg-4">
                    <div class="term-card">
                        <strong>参数范围：</strong> 速度参数需在0-255之间
                    </div>
                </div>
                <div class="col-md-6 col-lg-4">
                    <div class="term-card">
                        <strong>编码适配：</strong> 连接信息需用GBK编码解析
                    </div>
                </div>
                <div class="col-md-6 col-lg-4">
                    <div class="term-card">
                        <strong>架构匹配：</strong> 32位DLL仅支持32位程序
                    </div>
                </div>
                <div class="col-md-6 col-lg-4">
                    <div class="term-card">
                        <strong>权限要求：</strong> 始终以管理员身份运行程序
                    </div>
                </div>
            </div>
        </section>
    </main>

    <!-- 底部 -->
    <footer>
        <div class="container">
            <div class="footer-logo">幻魔K1鼠标控制器DLL 跨语言调用手册</div>
            <p>专业、稳定的串口鼠标控制解决方案</p>
            <div class="footer-copyright">© 2025 版权所有 | 版本：v1.1</div>
        </div>
    </footer>

    <!-- 核心脚本 -->
    <script src="https://lf3-cdn-tos.bytecdntp.com/cdn/expire-100-M/bootstrap/5.3.2/js/bootstrap.bundle.min.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/highlight.js/11.9.0/languages/csharp.min.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/highlight.js/11.9.0/languages/python.min.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/highlight.js/11.9.0/languages/cpp.min.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/highlight.js/11.9.0/languages/java.min.js"></script>

    <script>
        // 初始化代码高亮
        document.addEventListener('DOMContentLoaded', function() {
            if (typeof hljs !== 'undefined') {
                hljs.highlightAll();
            }
            // 初始化导航激活状态
            updateNavActive();
        });

        // 导航栏激活状态
        window.addEventListener('scroll', updateNavActive);
        function updateNavActive() {
            const sections = document.querySelectorAll('section[id]');
            const navLinks = document.querySelectorAll('.nav-link');
            let currentSection = '';

            sections.forEach(section => {
                const top = section.offsetTop - 100;
                const height = section.clientHeight;
                if (window.scrollY >= top && window.scrollY < top + height) {
                    currentSection = section.getAttribute('id');
                }
            });

            navLinks.forEach(link => {
                link.classList.toggle('active', link.getAttribute('href') === `#${currentSection}`);
            });
        }

        // 代码块折叠/展开
        function toggleCodeBlock(header) {
            const codeBlock = header.nextElementSibling;
            const btn = header.querySelector('.toggle-btn');
            codeBlock.classList.toggle('expanded');
            
            if (codeBlock.classList.contains('expanded')) {
                btn.innerHTML = '<i class="fa-solid fa-chevron-up"></i> 收起代码';
                if (typeof hljs !== 'undefined') {
                    const code = codeBlock.querySelector('code');
                    if (code) hljs.highlightElement(code);
                }
            } else {
                btn.innerHTML = '<i class="fa-solid fa-chevron-down"></i> 展开代码';
            }
        }

        // FAQ折叠/展开
        function toggleFaq(header) {
            const body = header.nextElementSibling;
            const icon = header.querySelector('i');
            body.style.display = body.style.display === 'none' ? 'block' : 'none';
            icon.classList.toggle('fa-chevron-up');
            icon.classList.toggle('fa-chevron-down');
        }
    </script>
</body>
</html>